﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Text.RegularExpressions;

namespace QuickAppLibrary
{
    /// <summary>
    /// Extends Functionality for WebBrowser. Provides the application logic in filling out 
    /// fields in HTML documents.
    /// </summary>
    public class WebBrowserExtensions
    {
        //Class Varibles
        private WebBrowser _browser;
        private HtmlDocument _webDoc;
        private HtmlElementCollection _elemColl;

        //Properties
        /// <summary>
        /// Exposes the WebBrowser Object (Read-Only)
        /// </summary>
        public WebBrowser WebBrowser
        {
            get
            {
                return _browser;
            }
        }

        //Constructor
        /// <summary>
        /// Constructor, assigns the WebBrowser
        /// </summary>
        /// <param name="browser"></param>
        public WebBrowserExtensions(WebBrowser browser)
        {
            this._browser = browser;
        }

        /// <summary>
        /// Loads the WebBrowser to the specific URL-string (Short-hand)
        /// </summary>
        /// <param name="url"></param>
        public void Navigate(string url)
        {
            this._browser.Navigate(url);
        }

        /// <summary>
        /// Fills out the Application info in the current WebBrowser
        /// </summary>
        /// <param name="applicationInfo"></param>
        public void FillApplication(ApplicationInfo applicationInfo)
        {
            _webDoc = _browser.Document;
            _elemColl = _webDoc.GetElementsByTagName("HTML");
            FillFormApplication(_elemColl, applicationInfo);
        }

        /// <summary>
        /// Fills out Resume & Cover Letter info in the current WebBrowser
        /// </summary>
        /// <param name="applicationInfo"></param>
        public void FillResume(ApplicationInfo applicationInfo)
        {
            _webDoc = _browser.Document;
            _elemColl = _webDoc.GetElementsByTagName("HTML");
            FillFormResume(_elemColl, applicationInfo);
        }

        /// <summary>
        /// Fills out the prior employers section in the current WebBrowser
        /// </summary>
        /// <param name="employerCollection"></param>
        public void FillEmployers(PriorEmployerCollection employerCollection)
        {
            _webDoc = _browser.Document;
            _elemColl = _webDoc.GetElementsByTagName("HTML");
            FillFormPriorEmployers(_elemColl, employerCollection);
        }

        //Fill Resume & Cover Letter in the web browser
        //Recursive Method
        private void FillFormResume(HtmlElementCollection elemColl, ApplicationInfo myInfo)
        {
            //Loop through all HTML tags
            if (_webDoc != null)
            {
                string elemId;
                foreach (HtmlElement elem in elemColl)
                {
                    try
                    {
                        //Eventually turn this into a Dictionary where key is the HTML element, 
                        //key is the object associated with it
                        if (elem.Id != null)
                        {
                            //Find corresponding element information & fill
                            elemId = elem.Id;

                            //Set Cover letter and resume info
                            if (TestRegExpression(elemId, "resume"))
                                elem.SetAttribute("value", myInfo.resumeText);
                            if (TestRegExpression(elemId, "cover"))
                                elem.SetAttribute("value", myInfo.coverLetter);
                        }
                    }
                    catch (ArgumentNullException ex)
                    {
                        MessageBox.Show(ex.StackTrace);
                    }
                    //Recursive method to recheck each child element of the current document
                    if (elem.CanHaveChildren)
                    {
                        FillFormResume(elem.Children, myInfo);
                    }
                }
            }
        }

        //Fills out the Application fields in the web browser
        //Recursive Method
        private void FillFormApplication(HtmlElementCollection elemColl, ApplicationInfo myInfo)
        {
            //Loop through all HTML tags
            if (_webDoc != null)
            {
                string elemId;
                foreach (HtmlElement elem in elemColl)
                {
                    try
                    {
                        //Eventually turn this into a Dictionary where key is the HTML element, 
                        //key is the object associated with it
                        if (elem.Id != null)
                        {
                            //Find corresponding element information & fill
                            elemId = elem.Id;
                            //Basic Contract Info
                            if (TestRegExpression(elemId, "first") || TestRegExpression(elemId, "fname"))
                            {
                                elem.SetAttribute("value", myInfo.firstName);
                            }

                            if (TestRegExpression(elemId, "mname") || TestRegExpression(elemId, "mid") || TestRegExpression(elemId, "midname"))
                            {
                                elem.SetAttribute("value", myInfo.middleName);
                            }

                            if (TestRegExpression(elemId, "last") || TestRegExpression(elemId, "lname"))
                            {
                                elem.SetAttribute("value", myInfo.lastName);
                            }

                            //Set Address
                            if (TestRegExpression(elemId, "street"))
                            {
                                elem.SetAttribute("value", myInfo.street);
                            }

                            if (TestRegExpression(elemId, "city"))
                            {
                                elem.SetAttribute("value", myInfo.city);
                            }

                            if (TestRegExpression(elemId, "state"))
                            {
                                elem.SetAttribute("value", myInfo.state);
                            }

                            if (TestRegExpression(elemId, "zip"))
                            {
                                elem.SetAttribute("value", myInfo.zip);
                            }

                            //Set Phones
                            if (TestRegExpression(elemId, "phone") || TestRegExpression(elemId, "homeph"))
                            {
                                elem.SetAttribute("value", myInfo.mainPhone);
                            }

                            if (TestRegExpression(elemId, "workphone"))
                            {
                                elem.SetAttribute("value", myInfo.workPhone);
                            }

                            if (TestRegExpression(elemId, "cell"))
                            {
                                elem.SetAttribute("value", myInfo.cellPhone);
                            }

                            //Email
                            if (TestRegExpression(elemId, "email"))
                            {
                                elem.SetAttribute("value", myInfo.email);
                            }

                            //Set Avaliablity
                            if (TestRegExpression(elemId, "available"))
                            {
                                elem.SetAttribute("value", myInfo.availDateString);
                            }

                            //Set Salary 
                            if (TestRegExpression(elemId, "salary"))
                            {
                                elem.SetAttribute("value", myInfo.desiredSalary);
                            }

                            //Set Education
                            //for High School
                            if (TestRegExpression(elemId, "hsname") || TestRegExpression(elemId, "high_school"))
                            {
                                elem.SetAttribute("value", myInfo.highSchool);
                            }
                            //for city
                            if (TestRegExpression(elemId, "hscity") || TestRegExpression(elemId, "high_school_city"))
                            {
                                elem.SetAttribute("value", myInfo.highSchoolCity);
                            }
                            //for state
                            if (TestRegExpression(elemId, "hsstate") || TestRegExpression(elemId, "high_school_state"))
                                elem.SetAttribute("value", myInfo.highSchoolState);

                            //For College
                            if (TestRegExpression(elemId, "college") || TestRegExpression(elemId, "schoolname"))
                                elem.SetAttribute("value", myInfo.college);
                            //for city
                            if (TestRegExpression(elemId, "collegecity") || TestRegExpression(elemId, "schoolcity"))
                                elem.SetAttribute("value", myInfo.collegeCity);
                            //for state
                            if (TestRegExpression(elemId, "collegestate") || TestRegExpression(elemId, "schoolstate"))
                                elem.SetAttribute("value", myInfo.collegeState);
                            //degree 
                            if (TestRegExpression(elemId, "degree"))
                                elem.SetAttribute("value", myInfo.collegeDegree);
                            //major
                            if (TestRegExpression(elemId, "major"))
                                elem.SetAttribute("value", myInfo.collegeMajor);

                            //For Other College
                            if (TestRegExpression(elemId, "otherschool") || TestRegExpression(elemId, "technical"))
                                elem.SetAttribute("value", myInfo.otherSchool);
                            //for city
                            if (TestRegExpression(elemId, "othercity") || TestRegExpression(elemId, "other_school_city"))
                                elem.SetAttribute("value", myInfo.otherSchoolCity);
                            //for state
                            if (TestRegExpression(elemId, "otherstate") || TestRegExpression(elemId, "other_school_state"))
                                elem.SetAttribute("value", myInfo.otherSchoolState);
                            //degree 
                            if (TestRegExpression(elemId, "otherdegree"))
                                elem.SetAttribute("value", myInfo.otherSchoolDegree);
                            //major
                            if (TestRegExpression(elemId, "othermajor"))
                                elem.SetAttribute("value", myInfo.otherSchoolMajor);

                            //Set Cover letter and resume info
                            if (TestRegExpression(elemId, "resume"))
                                elem.SetAttribute("value", myInfo.resumeText);
                            if (TestRegExpression(elemId, "cover"))
                                elem.SetAttribute("value", myInfo.coverLetter);
                        }
                    }
                    catch (ArgumentNullException ex)
                    {
                        MessageBox.Show(ex.StackTrace);
                    }
                    //Recursive method to recheck each child element of the current document
                    if (elem.CanHaveChildren)
                    {
                        FillFormApplication(elem.Children, myInfo);
                    }
                }
            }
        }

        //Fills out the Prior Employers in the web browser
        //Recursive Method
        private void FillFormPriorEmployers(HtmlElementCollection elemColl, PriorEmployerCollection employerCollection)
        {
            try
            {
                //Loop through all HTML tags
                if (_webDoc != null)
                {
                    string elemId;
                    foreach (HtmlElement elem in elemColl)
                    {
                        //Eventually turn this into a Dictionary where key is the HTML element, 
                        //key is the object associated with it
                        if (elem.Id != null)
                        {
                            //Find corresponding element information & fill
                            elemId = elem.Id;

                            //Find employment history
                            //Make sure employer collection isn't empty
                            int empCount = 1;
                            foreach (PriorEmployer emp in employerCollection)
                            {
                                if (TestRegExpression(elemId, "companyname." + empCount) || TestRegExpression(elemId, "Company." + empCount))
                                {
                                    elem.SetAttribute("value", emp.business);
                                }

                                if (TestRegExpression(elemId, "businesstype." + empCount) || TestRegExpression(elemId, "business." + empCount))
                                {
                                    elem.SetAttribute("value", emp.businessType);
                                }

                                if (TestRegExpression(elemId, "address." + empCount) || TestRegExpression(elemId, "address" + empCount))
                                {
                                    elem.SetAttribute("value", emp.street);
                                }

                                if (TestRegExpression(elemId, "city." + empCount) || TestRegExpression(elemId, "city" + empCount))
                                {
                                    elem.SetAttribute("value", emp.city);
                                }

                                if (TestRegExpression(elemId, "state." + empCount) || TestRegExpression(elemId, "state" + empCount))
                                {
                                    elem.SetAttribute("value", emp.state);
                                }

                                if (TestRegExpression(elemId, "zip." + empCount) || TestRegExpression(elemId, "zip" + empCount))
                                {
                                    elem.SetAttribute("value", emp.zip);
                                }

                                if (TestRegExpression(elemId, "state." + empCount) || TestRegExpression(elemId, "state" + empCount))
                                {
                                    elem.SetAttribute("value", emp.state);
                                }

                                //Change later to evaluate culture/geography settings!
                                if (TestRegExpression(elemId, "country." + empCount) || TestRegExpression(elemId, "country" + empCount))
                                {
                                    elem.SetAttribute("value", "United States");
                                }

                                if (TestRegExpression(elemId, "jobtitle." + empCount) || TestRegExpression(elemId, "title" + empCount))
                                {
                                    elem.SetAttribute("value", emp.businessTitle);
                                }

                                if (TestRegExpression(elemId, "from." + empCount) || TestRegExpression(elemId, "from" + empCount))
                                {
                                    elem.SetAttribute("value", emp.businessFromString);
                                }

                                if (TestRegExpression(elemId, "to." + empCount) || TestRegExpression(elemId, "to" + empCount))
                                {
                                    elem.SetAttribute("value", emp.businessToString);
                                }

                                if (TestRegExpression(elemId, "supervisorname." + empCount) || TestRegExpression(elemId, "name" + empCount))
                                {
                                    elem.SetAttribute("value", emp.businessManager);
                                }

                                if (TestRegExpression(elemId, "tel." + empCount) || TestRegExpression(elemId, "phone" + empCount))
                                {
                                    elem.SetAttribute("value", emp.businessPhone);
                                }

                                if (TestRegExpression(elemId, "sal." + empCount) || TestRegExpression(elemId, "salary" + empCount))
                                {
                                    elem.SetAttribute("value", emp.businessSalary);
                                }

                                if (TestRegExpression(elemId, "reason." + empCount) || TestRegExpression(elemId, "reason" + empCount))
                                {
                                    elem.SetAttribute("value", emp.businessReasonsForLeaving);
                                }

                                if (TestRegExpression(elemId, "responsibility." + empCount) || TestRegExpression(elemId, "responsiblities" + empCount))
                                {
                                    elem.SetAttribute("value", emp.businessResponsibilities);
                                }

                                //Add to empCount
                                empCount++;
                            }
                        }
                        //Recursive method to recheck each child element of the current document
                        if (elem.CanHaveChildren)
                        {
                            FillFormPriorEmployers(elem.Children, employerCollection);
                        }
                    }
                }
            }
            //Exceptions
            catch (ArgumentNullException ex)
            {
                MessageBox.Show(ex.StackTrace);
            }
            catch (StackOverflowException ex)
            {
                MessageBox.Show(ex.StackTrace);
            }
        }

        /// <summary>
        /// Evaluates if a regular expression exists in a given string (specifically for an HTML string)
        /// htmlElement is evaluated and testStr is the evaluator
        /// </summary>
        /// <param name="htmlElement"></param>
        /// <param name="testStr"></param>
        /// <returns>Boolean</returns>
        public static bool TestRegExpression(string htmlElement, string testStr)
        {
            if (Regex.IsMatch(htmlElement, testStr, RegexOptions.IgnoreCase))
            {
                return true;
            }
            else
            {
                return false;
            }
        }
    }
}
